import EventManager from "../../core/EventManager";
import ResManager from "../../core/ResManager";
import ObjectUtil from "../../utils/ObjectUtil";
import { Utils } from "../../utils/Utils";
import Constants from "./Constants";
import Jewel from "./Jewel";
import NodePool from "../../core/NodePool";
import JewelData from "./JewelData";
import BaseScene from "../../core/BaseScene";
import LogUtil from "../../utils/LogUtil";

const { ccclass, property } = cc._decorator;

@ccclass
export default class JewelsGrid extends BaseScene {
    @property({ type: cc.Sprite, tooltip: CC_DEV && '背景图' })
    public background: cc.Sprite = null;

    @property({ type: cc.ProgressBar, tooltip: CC_DEV && '进度条' })
    public progressBar: cc.ProgressBar = null;

    @property({ type: cc.Node, tooltip: CC_DEV && '游戏节点' })
    public gameNode: cc.Node = null;

    @property({ type: cc.Node, tooltip: CC_DEV && '宝石布局节点' })
    public gridNode: cc.Node = null;

    @property({ type: cc.Prefab, tooltip: CC_DEV && '宝石预制' })
    public itemJewel: cc.Prefab = null;

    @property({ type: cc.Label, tooltip: CC_DEV && '分数' })
    public labScore: cc.Label = null;

    private m_row: number;//行数
    private m_col: number;//列数

    private m_jewelSelected: Jewel = null; //当前选择的宝石
    private m_jewelSwapped: Jewel = null; //欲交换的宝石

    private m_JewelsBox: Jewel[][];//存放宝石对象的容器，通过坐标索引宝石
    private m_crushJewelBox: Jewel[] = [];//准备消除的宝石容器
    private m_newJewelBox: Jewel[] = [];//准备加入布局的宝石的容器

    private resNum: number;//资源数

    private pauseTouch: boolean = false; //暂停触摸逻辑
    private config_language: any;

    onLoad(): void {
        super.onLoad();
        //加载资源
        let obj = {
            resourceId: "sourceList",
            resourcePath: 'config/sourceList',
            resourceType: 'csv',
            key: ["resourceId"],
        }
        this.gameNode.active = false;
        this.progressBar.progress = 0;
        this.resNum = 0;
        JewelData.ins().score = 0;
        ResManager.ins().load(obj, () => {
            let cfg = ResManager.ins().getRes("sourceList");
            let list = ObjectUtil.objConvertArray(cfg);
            this.resNum = list.length;
            this.loadingRes(list, 0);
        }, this.node);
    }

    loadingRes(list: any[], idx: number): void {
        if (list[idx]) {
            ResManager.ins().load(list[idx], () => {
                idx++;
                this.progressBar.progress = idx / this.resNum;
                this.loadingRes(list, idx);
            }, this.node);
        } else {
            this.progressBar.progress = 1;
            this.gameNode.active = true;
            LogUtil.log(LogUtil.getFileName(),"资源加载完毕");
            this.initNodePool();
        }
    }

    //加载对象池
    initNodePool(): void {
        LogUtil.log(LogUtil.getFileName(),'加载对象池');
        let obj = {
            name: "jewels",
            initPollCount: Constants.GRID_ROW * Constants.GRID_COL + 20,
            prefab: this.itemJewel
        }
        NodePool.initObjPool(NodePool.mPool, obj, () => {
            this.init(Constants.GRID_ROW, Constants.GRID_COL);
        });
    }

    public init(row: number, col: number): void {
        this.m_row = row;
        this.m_col = col;

        this.m_jewelSelected = null;
        this.m_jewelSwapped = null;

        //1.根据布局大小创建出宝石阵列
        //2.布局坐标以左下角为原点，x右y上为正方向
        this.m_JewelsBox = [];
        for (let x = 0; x < this.m_col; x++) {
            if (!this.m_JewelsBox[x]) this.m_JewelsBox[x] = [];
            for (let y = 0; y < this.m_row; y++) {
                this.m_JewelsBox[x][y] = this.createAJewel(x, y);
            }
        }

        while (this.isDeadMap()) {
            LogUtil.log(LogUtil.getFileName(),"dead map! need to update");
            this.updateMap();
        }

        //加入触摸监听
        this.gridNode.on(cc.Node.EventType.TOUCH_START, this.onTouchBegan, this);
        this.gridNode.on(cc.Node.EventType.TOUCH_MOVE, this.onTouchMoved, this);
        //更新分数
        EventManager.on('updateScore', this.updateScore, this);

        this.config_language = ResManager.ins().getRes('config_language');
    }

    public updateScore(): void {
        this.labScore.string = this.config_language['jewel_score'].text.format([JewelData.ins().score]);
    }

    public isDeadMap(): boolean {
        //模拟交换，判断交换后是否能消除，如不能，那么就是个死图 (方法有问题变量不会交换)
        // let swap = (a: Jewel, b: Jewel) => {
        //     let temp = a;
        //     a = b;
        //     b = temp;
        // };

        let isDeadMap = true;
        this.m_crushJewelBox = [];
        //遍历每一颗宝石
        for (let x = 0; x < this.m_col; x++) {
            for (let y = 0; y < this.m_row; y++) {
                //跟左边的交换
                if (x > 0) {
                    // this.swap(this.m_JewelsBox[x][y], this.m_JewelsBox[x - 1][y]);
                    {
                        let temp = this.m_JewelsBox[x][y];
                        this.m_JewelsBox[x][y] = this.m_JewelsBox[x - 1][y];
                        this.m_JewelsBox[x - 1][y] = temp;
                    }
                    if (this.canCrush())
                        isDeadMap = false;
                    // this.swap(this.m_JewelsBox[x][y], this.m_JewelsBox[x - 1][y]);
                    {
                        let temp = this.m_JewelsBox[x][y];
                        this.m_JewelsBox[x][y] = this.m_JewelsBox[x - 1][y];
                        this.m_JewelsBox[x - 1][y] = temp;
                    }
                }

                //跟右边的交换
                if (x < this.m_col - 1) {
                    // this.swap(this.m_JewelsBox[x][y], this.m_JewelsBox[x + 1][y]);
                    {
                        let temp = this.m_JewelsBox[x][y];
                        this.m_JewelsBox[x][y] = this.m_JewelsBox[x + 1][y];
                        this.m_JewelsBox[x + 1][y] = temp;
                    }
                    if (this.canCrush())
                        isDeadMap = false;
                    // this.swap(this.m_JewelsBox[x][y], this.m_JewelsBox[x + 1][y]);
                    {
                        let temp = this.m_JewelsBox[x][y];
                        this.m_JewelsBox[x][y] = this.m_JewelsBox[x + 1][y];
                        this.m_JewelsBox[x + 1][y] = temp;
                    }
                }

                //跟上面的交换
                if (y < this.m_row - 1) {
                    // this.swap(this.m_JewelsBox[x][y], this.m_JewelsBox[x][y + 1]);
                    {
                        let temp = this.m_JewelsBox[x][y];
                        this.m_JewelsBox[x][y] = this.m_JewelsBox[x][y + 1];
                        this.m_JewelsBox[x][y + 1] = temp;
                    }
                    if (this.canCrush())
                        isDeadMap = false;
                    // this.swap(this.m_JewelsBox[x][y], this.m_JewelsBox[x][y + 1]);
                    {
                        let temp = this.m_JewelsBox[x][y];
                        this.m_JewelsBox[x][y] = this.m_JewelsBox[x][y + 1];
                        this.m_JewelsBox[x][y + 1] = temp;
                    }
                }

                //跟下面的交换
                if (y > 0) {
                    // this.swap(this.m_JewelsBox[x][y], this.m_JewelsBox[x][y - 1]);
                    {
                        let temp = this.m_JewelsBox[x][y];
                        this.m_JewelsBox[x][y] = this.m_JewelsBox[x][y - 1];
                        this.m_JewelsBox[x][y - 1] = temp;
                    }
                    if (this.canCrush())
                        isDeadMap = false;
                    // this.swap(this.m_JewelsBox[x][y], this.m_JewelsBox[x][y - 1]);
                    {
                        let temp = this.m_JewelsBox[x][y];
                        this.m_JewelsBox[x][y] = this.m_JewelsBox[x][y - 1];
                        this.m_JewelsBox[x][y - 1] = temp;
                    }
                }
            }
        }

        //canCrush会存储能消除的宝石进去，由于是模拟交换，所以还要清空
        this.m_crushJewelBox = [];

        return isDeadMap;
    }

    public canCrush(): boolean {
        //该函数判断当前状态的宝石阵列是否能消除
        //将能消除的宝石加入消除宝石盒子，等待消除

        let count = 0; //连续数
        let JewelBegin: Jewel = null; //起始遍历的宝石
        let JewelNext: Jewel = null; //从起始宝石开始往前遍历的宝石

        //遍历每一列
        for (let x = 0; x < this.m_col; x++) {
            for (let y = 0; y < this.m_row - 1;) {
                count = 1;
                JewelBegin = this.m_JewelsBox[x][y];
                JewelNext = this.m_JewelsBox[x][y + 1];
                //如果连续出现同类型
                while (JewelBegin.getType() == JewelNext.getType()) {
                    count++;
                    let nextIndex = y + count;
                    if (nextIndex > this.m_row - 1)
                        break;
                    JewelNext = this.m_JewelsBox[x][nextIndex];
                }
                //如果连续数大于等于3，那么遍历的这些宝石应当消除，把它们存入消除宝石盒子
                if (count >= 3) {
                    for (let n = 0; n < count; n++) {
                        let jewel = this.m_JewelsBox[x][y + n];
                        this.m_crushJewelBox.push(jewel);
                    }
                }
                y += count;
            }
        }

        //遍历每一行，逻辑和遍历每一列是一样的
        for (let y = 0; y < this.m_row; y++) {
            for (let x = 0; x < this.m_col - 1;) {
                count = 1;
                JewelBegin = this.m_JewelsBox[x][y];
                JewelNext = this.m_JewelsBox[x + 1][y];

                while (JewelBegin.getType() == JewelNext.getType()) {
                    count++;
                    let nextIndex = x + count;
                    if (nextIndex > this.m_col - 1)
                        break;
                    JewelNext = this.m_JewelsBox[nextIndex][y];
                }
                if (count >= 3) {
                    for (let n = 0; n < count; n++) {
                        let jewel = this.m_JewelsBox[x + n][y];
                        //有可能有宝石同时行列可消除，那么不能重复存储到消除宝石盒子，故需添加一次判断
                        if (this.m_crushJewelBox.lastIndexOf(jewel) != -1) {
                            continue;
                        }
                        this.m_crushJewelBox.push(jewel);
                    }
                }
                x += count;
            }
        }

        //如果消除宝石盒子不为空，那么说明该阵列可消除，返回真
        if (this.m_crushJewelBox.length > 0) {
            return true;
        }
        else {
            return false;
        }
    }

    public updateMap(): void {
        for (let x = 0; x < this.m_col; x++) {
            for (let y = 0; y < this.m_row; y++) {
                NodePool.backObjPool(NodePool.mPool, { name: "jewels", prefab: this.m_JewelsBox[x][y].node });
                // this.m_JewelsBox[x][y].node.destroy();
                this.m_JewelsBox[x][y] = this.createAJewel(x, y);
            }
        }
        LogUtil.log(LogUtil.getFileName(),"update a new map!");
    }

    createAJewel(x: number, y: number): Jewel {
        //1.根据布局坐标创建一颗宝石，类型随机
        //2.判断该宝石是否合法（不会三消）
        //3.设置该宝石的世界坐标
        //4.将该宝石加入渲染节点
        let jewel: Jewel = null;

        while (1) {
            let node = NodePool.getNewNode(NodePool.mPool["jewelsPool"], this.itemJewel, null);
            // let node = cc.instantiate(this.itemJewel);
            jewel = node.getComponent(Jewel);
            jewel.init(Utils.getRandomInt(Constants.FIRST_JEWEL_ID, Constants.LAST_JEWEL_ID), x, y);

            if (this.isJewelLegal(jewel, x, y)) {
                break;
            }
        }

        this.setJewelPixPos(jewel, x, y);
        this.gridNode.addChild(jewel.node);

        // LogUtil.log(LogUtil.getFileName(),"add a jewel!---type:%d---x:%d---y:%d", jewel.getType(), x, y);

        return jewel;
    }

    isJewelLegal(jewel: Jewel, x: number, y: number): boolean {
        //1.分别判断新加入的宝石在x轴y轴方向是否会三消
        //2.由于是从正方向加入宝石，因此只需往负方向判断
        //3.x，y坐标小于等于1不必判断
        //4.两轴同时合法方合法
        let isXLegal: boolean = true;
        let isYLegal: boolean = true;

        if (x > 1) {
            //向x轴负方向分别比较两位，如果宝石类型都一样，那么表示三消，该宝石不合法
            if (jewel.getType() == this.m_JewelsBox[x - 1][y].getType() &&
                jewel.getType() == this.m_JewelsBox[x - 2][y].getType()
            ) {
                isXLegal = false;
            }
            else
                isXLegal = true;
        }

        if (y > 1) {
            //向y轴负方向分别比较两位，如果宝石类型都一样，那么表示三消，该宝石不合法
            if (jewel.getType() == this.m_JewelsBox[x][y - 1].getType() &&
                jewel.getType() == this.m_JewelsBox[x][y - 2].getType()) {
                isYLegal = false;
            }
            else
                isYLegal = true;
        }

        return isXLegal && isYLegal;
    }

    setJewelPixPos(jewel: Jewel, x: number, y: number): void {
        let benginPos = Constants.GRID_WIDTH / 2;
        jewel.setPosition(x * Constants.GRID_WIDTH + benginPos, y * Constants.GRID_WIDTH + benginPos);
    }

    onTouchBegan(event) {
        if (this.pauseTouch) return false;
        let pos = this.gridNode.convertToNodeSpaceAR(event.getLocation());
        LogUtil.log(LogUtil.getFileName(),'onTouchBegan');
        //是否有按在宝石布局上
        let rect = new cc.Rect(0, 0, this.m_col * Constants.GRID_WIDTH, this.m_row * Constants.GRID_WIDTH);
        if (rect.contains(pos)) {
            //得到布局坐标
            let x = Math.floor(pos.x / Constants.GRID_WIDTH);
            let y = Math.floor(pos.y / Constants.GRID_WIDTH);

            // 得到当前选中的宝石
            this.m_jewelSelected = this.m_JewelsBox[x][y];

            // LogUtil.log(LogUtil.getFileName(),"touch coordinate: x=%d,y=%d jewel's type:%d", x, y, this.m_jewelSelected.getType());

            return true;
        } else {
            return false;
        }
    }

    onTouchMoved(event) {
        if (this.pauseTouch) return;
        // LogUtil.log(LogUtil.getFileName(),'onTouchMoved');
        //如果没有选择宝石，那么返回
        if (!this.m_jewelSelected) {
            return;
        }

        //已选择宝石的布局坐标
        let startX = this.m_jewelSelected.getX();
        let startY = this.m_jewelSelected.getY();

        //触摸点的布局坐标
        let pos = this.gridNode.convertToNodeSpaceAR(event.getLocation());
        let touchX = Math.floor(pos.x / Constants.GRID_WIDTH);
        let touchY = Math.floor(pos.y / Constants.GRID_WIDTH);

        //如果触摸点不在布局内，或者触摸点布局坐标和已选宝石布局坐标一样，那么返回
        let rect = new cc.Rect(0, 0, this.m_col * Constants.GRID_WIDTH, this.m_row * Constants.GRID_WIDTH);
        if (!rect.contains(pos) || (touchX == startX && touchY == startY)) {
            return;
        }

        //判断已选宝石的布局坐标与触摸点的布局坐标是否直角相隔一个单位
        if (Math.abs(startX - touchX) + Math.abs(startY - touchY) != 1) {
            //log("touch pos not on border");
            return;
        }

        //余下的情况，触摸点上面的宝石就是欲进行交换的宝石
        //通过坐标索引，获取欲交换的宝石
        this.m_jewelSwapped = this.m_JewelsBox[touchX][touchY];

        //交换宝石，开启交换状态捕捉函数（在交换完成后，判断是否可以消除）
        // this.swapJewels(this.m_jewelSelected, this.m_jewelSwapped);
        {
            this.pauseTouch = true;
            //1.交换宝石容器内的宝石指针
            //2.交换宝石坐标
            //3.宝石移动到新的位置
            let jewelA = this.m_jewelSelected;
            let jewelB = this.m_jewelSwapped;
            let temp = this.m_JewelsBox[jewelA.getX()][jewelA.getY()];
            this.m_JewelsBox[jewelA.getX()][jewelA.getY()] = this.m_JewelsBox[jewelB.getX()][jewelB.getY()];
            this.m_JewelsBox[jewelB.getX()][jewelB.getY()] = temp;

            let tempX = jewelA.getX();
            jewelA.setX(jewelB.getX());
            jewelB.setX(tempX);

            let tempY = jewelA.getY();
            jewelA.setY(jewelB.getY());
            jewelB.setY(tempY);

            this.swapJewelToNewPos(jewelA);
            this.swapJewelToNewPos(jewelB);
        }
        this.schedule(this.onJewelsSwaping);
    }

    swapJewelToNewPos(jewel: Jewel): void {
        //移动开始设置宝石交换状态为真，移动结束再设置为假
        jewel.setSwapingState(true);
        cc.tween(jewel.node)
            .to(Constants.MOVE_SPEED, { position: cc.v3(jewel.getX() * Constants.GRID_WIDTH + Constants.GRID_WIDTH / 2, jewel.getY() * Constants.GRID_WIDTH + Constants.GRID_WIDTH / 2, 0) })
            .call(() => {
                jewel.setSwapingState(false);
            })
            .start();
    }

    onJewelsSwaping(dt): void {
        //捕捉两个正在交换的宝石的交换动作是否已经停止，如果没停止，返回继续捕捉
        if (this.m_jewelSelected.isSwaping() || this.m_jewelSwapped.isSwaping()) {
            return;
        }
        //如果宝石交换动作执行完毕
        else {
            this.unschedule(this.onJewelsSwaping);  //停止捕捉

            LogUtil.log(LogUtil.getFileName(),"swap over!");

            LogUtil.log(LogUtil.getFileName(),"is it can crush?");

            //判断是否当前状态可以消除
            if (this.canCrush()) {
                LogUtil.log(LogUtil.getFileName(),"yes,crush!");

                this.m_jewelSelected = null;

                //开始消除，开启消除状态捕捉函数(捕捉到消除完毕后，刷新布局)，这一轮消除正式开始
                // SimpleAudioEngine::getInstance()->playEffect("crush.ogg");
                this.goCrush();
                this.schedule(this.onJewelsCrushing);
            }
            else {
                LogUtil.log(LogUtil.getFileName(),"no, cant crush!");

                //不能消除，交换回去，开启交换返回时的捕捉函数(捕捉到消除完毕后，开启触摸接听)
                // SimpleAudioEngine::getInstance()->playEffect("swapback.ogg");
                // swapJewels(m_jewelSelected, m_jewelSwapped);
                {
                    this.pauseTouch = true;
                    //1.交换宝石容器内的宝石指针
                    //2.交换宝石坐标
                    //3.宝石移动到新的位置
                    let jewelA = this.m_jewelSelected;
                    let jewelB = this.m_jewelSwapped;
                    let temp = this.m_JewelsBox[jewelA.getX()][jewelA.getY()];
                    this.m_JewelsBox[jewelA.getX()][jewelA.getY()] = this.m_JewelsBox[jewelB.getX()][jewelB.getY()];
                    this.m_JewelsBox[jewelB.getX()][jewelB.getY()] = temp;

                    let tempX = jewelA.getX();
                    jewelA.setX(jewelB.getX());
                    jewelB.setX(tempX);

                    let tempY = jewelA.getY();
                    jewelA.setY(jewelB.getY());
                    jewelB.setY(tempY);

                    this.swapJewelToNewPos(jewelA);
                    this.swapJewelToNewPos(jewelB);
                }
                this.schedule(this.onJewelsSwapingBack);
            }
        }
    }

    goCrush() {
        LogUtil.log(LogUtil.getFileName(),'goCrush');
        //遍历消除宝石盒子，对其中的宝石进行消除操作
        for (let k in this.m_crushJewelBox) {
            //生成新的宝石，类型随机，初始位置在最上面一行的上边一行（布局外一格）
            let jewel = this.m_crushJewelBox[k];
            let node = NodePool.getNewNode(NodePool.mPool["jewelsPool"], this.itemJewel, null);
            // let node = cc.instantiate(this.itemJewel);
            let newJewel = node.getComponent(Jewel);
            newJewel.init(Utils.getRandomInt(Constants.FIRST_JEWEL_ID, Constants.LAST_JEWEL_ID), jewel.getX(), this.m_row);

            //将新宝石放到新宝石盒子内，等待加入布局
            this.m_newJewelBox.push(newJewel);

            //宝石盒子内应当刷新的宝石暂时置为空
            this.m_JewelsBox[jewel.getX()][jewel.getY()] = null;

            //原有宝石对象消除
            jewel.crush();
        }
    }

    onJewelsCrushing(dt): void {
        //捕捉宝石消除状态，如果有宝石还在消除，那么继续捕捉
        for (let k in this.m_crushJewelBox) {
            let jewel = this.m_crushJewelBox[k];
            if (jewel.isCrushing()) {
                //log("crushing");
                return;
            }
        }

        //如果全部宝石已经消除完毕，停止捕捉函数
        this.unschedule(this.onJewelsCrushing);

        this.m_crushJewelBox = []; //清空消除宝石盒子

        LogUtil.log(LogUtil.getFileName(),"crush over!");
        LogUtil.log(LogUtil.getFileName(),"begin to refresh!");

        //刷新宝石阵列，并开启刷新状态捕捉函数（刷新一遍结束，重新判断新阵列是否可消除）
        this.refreshJewelsGrid();
        this.schedule(this.onJewelsRefreshing);
    }

    onJewelsSwapingBack(dt): void {
        //捕捉两个正在交换的宝石的交换动作是否已经停止，如果没停止，返回继续捕捉
        if (this.m_jewelSelected.isSwaping() || this.m_jewelSwapped.isSwaping()) {
            return;
        }
        else {
            this.unschedule(this.onJewelsSwapingBack); //停止捕捉

            LogUtil.log(LogUtil.getFileName(),"swap back!");

            this.m_jewelSelected = null;

            // _eventDispatcher->resumeEventListenersForTarget(this); //重新开始触摸接听
            this.pauseTouch = false;
        }
    }

    refreshJewelsGrid(): void {
        //遍历列，如果该列有空位，那么应当刷新
        for (let x = 0; x < this.m_col; x++) {
            let empty_count = 0; //一列总的空格子数

            for (let y = 0; y < this.m_row; y++) {
                //根据坐标索引宝石盒子内的宝石指针，如果为空，那么说明该坐标位置为空
                let jewel = this.m_JewelsBox[x][y];
                if (!jewel)
                    empty_count++;
            }
            if (empty_count) {
                LogUtil.log(LogUtil.getFileName(),"the %d col has %d empty", x, empty_count);
                //找到有空位的列，刷新该列的宝石
                this.refreshJewelsToNewPos(x);
            }
        }
    }

    refreshJewelsToNewPos(col: number): void {
        //刷新该列上面的宝石
        let n = 0; //当前遍历到的空位数
        let pJewelsbox = this.m_JewelsBox; //保存一个宝石盒子的指针，这是为了让其能传入lamda

        //先让现有的宝石下落
        for (let y = 0; y < this.m_row; y++) {
            let jewel = this.m_JewelsBox[col][y];

            if (!jewel) {
                n++;
                continue;
            }
            else if (n != 0) {
                jewel.setY(jewel.getY() - n);

                cc.tween(jewel.node)
                    .by(Constants.MOVE_SPEED, { position: cc.v3(0, -n * Constants.GRID_WIDTH, 0) })
                    .call(() => {
                        pJewelsbox[jewel.getX()][jewel.getY()] = jewel;
                    })
                    .start();
            }
        }

        //再让新宝石下落
        let i = n;
        let delta = 1;
        for (let k in this.m_newJewelBox) {
            let jewel = this.m_newJewelBox[k];
            if (jewel && jewel.getX() == col) {
                this.setJewelPixPos(jewel, jewel.getX(), jewel.getY());
                this.gridNode.addChild(jewel.node);
                jewel.setY(this.m_row - i);
                cc.tween(jewel.node)
                    .delay(0.2)
                    .by(Constants.MOVE_SPEED * delta++, { position: cc.v3(0, -i-- * Constants.GRID_WIDTH, 0) })
                    .call(() => {
                        pJewelsbox[jewel.getX()][jewel.getY()] = jewel;
                        // this.m_newJewelBox.splice(parseInt(k), 1);
                        //上面方法有问题该写下
                        this.m_newJewelBox[k] = null;
                        if (this.checkListNull(this.m_newJewelBox)) this.m_newJewelBox = [];

                    })
                    .start();
            }
        }
    }

    checkListNull(list: any[]): boolean {
        let blt = true;
        for (let k in list) {
            if (list[k]) blt = false;
        }
        return blt;
    }

    onJewelsRefreshing(dt): void {
        //捕捉宝石刷新状态，如果新宝石盒子还有宝石（即新宝石还在刷新当中），那么继续捕捉
        if (this.m_newJewelBox.length != 0) {
            LogUtil.log(LogUtil.getFileName(),"refreshing!", this.m_newJewelBox.length);
            return;
        }
        else {
            this.unschedule(this.onJewelsRefreshing);

            LogUtil.log(LogUtil.getFileName(),"refresh over!");
            LogUtil.log(LogUtil.getFileName(),"and now, is it can crush?");

            if (this.canCrush()) {
                LogUtil.log(LogUtil.getFileName(),"yes, crush again!");

                //如果能消除，那么继续消除
                // SimpleAudioEngine::getInstance()->playEffect("crush.ogg");
                this.goCrush();
                this.schedule(this.onJewelsCrushing);
            }
            else {
                LogUtil.log(LogUtil.getFileName(),"no, cant crush! over!");

                //判断是否为死图，如果是，则执行一段文字动画，提示即将更新地图
                if (this.isDeadMap()) {
                    LogUtil.log(LogUtil.getFileName(),"cant crush any more, updating a new map!");

                    let node = new cc.Node();
                    node.addComponent(cc.Label);
                    node.color = cc.Color.RED;
                    node.y = 100;
                    let lab = node.getComponent(cc.Label);
                    lab.fontSize = 20;
                    lab.string = '没有可消除了，即将更新地图';
                    this.node.addChild(node);
                    cc.tween(node)
                        .to(0.8, { opacity: 100 }, { easing: 'backIn' })
                        .call(() => {
                            node.destroy();//直接销毁
                            do {
                                this.updateMap();
                            } while (this.isDeadMap());
                            this.pauseTouch = false;
                        })
                        .start();
                }
                else {
                    //如果不是死图，那么就直接开启触摸监听，等待下一轮的交互操作
                    // _eventDispatcher->resumeEventListenersForTarget(this);
                    this.pauseTouch = false;
                }
            }
        }
    }



    onBtnClick() {
        // this.updateMap();
        // LogUtil.log(LogUtil.getFileName(),NodePool.mPool)
    }

}